package com.campus.counseling.scoring;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.campus.counseling.model.vo.TestQuestionVO;
import com.campus.counseling.service.TestQuestionService;
import com.campus.counseling.service.PsychologicalTestService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component("dimensionScorer")
@RequiredArgsConstructor
public class DimensionScorer implements ScoringEngine {

    private final TestQuestionService testQuestionService;
    private final PsychologicalTestService psychologicalTestService;
    private final ObjectMapper objectMapper;

    @Override
    public Map<String, Double> calculateDimensionScores(Long testId, Map<Long, String> answers) {
        log.info("开始计算维度得分, testId: {}, 答案数量: {}", testId, answers.size());
        
        // 获取测试题目
        List<TestQuestionVO> questions = testQuestionService.getQuestionsByTestId(testId);
        log.info("获取到题目数量: {}", questions.size());
        
        // 获取维度配置
        List<Map<String, Object>> dimensions = psychologicalTestService.getTestDimensions(testId);
        log.info("获取到维度配置: {}", dimensions);
        
        // 按维度分组计算得分
        Map<String, List<Double>> dimensionScores = new HashMap<>();
        
        for (TestQuestionVO question : questions) {
            String answer = answers.get(question.getId());
            if (answer == null) {
                log.warn("题目{}未作答", question.getId());
                continue;
            }
            
            try {
                double score = calculateQuestionScore(question, answer);
                String dimension = question.getDimension();
                dimensionScores.computeIfAbsent(dimension, k -> new ArrayList<>()).add(score);
                log.info("题目{} 维度{} 答案{} 得分{}", question.getId(), dimension, answer, score);
            } catch (Exception e) {
                log.error("计算题目{}分数时出错: {}", question.getId(), e.getMessage());
            }
        }
        
        // 计算维度得分
        Map<String, Double> result = new HashMap<>();
        for (Map.Entry<String, List<Double>> entry : dimensionScores.entrySet()) {
            String dimension = entry.getKey();
            List<Double> scores = entry.getValue();
            
            if (!scores.isEmpty()) {
                // 计算维度原始分
                double rawScore = scores.stream().mapToDouble(Double::doubleValue).sum();
                
                // 获取维度配置
                Map<String, Object> dimensionConfig = dimensions.stream()
                    .filter(d -> dimension.equals(d.get("dimensionKey")))
                    .findFirst()
                    .orElse(null);

                if (dimensionConfig != null) {
                    // 获取权重，如果未配置则默认为1
                    Object weightObj = dimensionConfig.get("weight");
                    BigDecimal weight = BigDecimal.ONE; // 默认权重为1
                    if (weightObj != null) {
                        try {
                            weight = new BigDecimal(weightObj.toString());
                        } catch (NumberFormatException e) {
                            log.warn("维度{}的权重配置无效: {}", dimension, weightObj);
                        }
                    }
                    
                    // 应用权重
                    double weightedScore = rawScore * weight.doubleValue();
                    result.put(dimension, weightedScore);
                    log.info("维度{} 原始分: {} 权重: {} 加权得分: {}", 
                        dimension, rawScore, weight, weightedScore);
                } else {
                    log.warn("维度{}未找到配置，使用原始分", dimension);
                    result.put(dimension, rawScore);
                }
            }
        }
        
        return result;
    }

    private double calculateQuestionScore(TestQuestionVO question, String answer) {
        try {
            Map<String, BigDecimal> optionScores = question.getOptionScores();
            List<String> options = question.getOptions();
            
            if (optionScores == null || optionScores.isEmpty()) {
                log.warn("题目{}未配置选项分值", question.getId());
                return 0.0;
            }

            if (options == null || options.isEmpty()) {
                log.warn("题目{}未配置选项", question.getId());
                return 0.0;
            }

            // 将字母答案转换为数字索引（A=1, B=2, C=3, D=4, E=5）
            int answerNumber;
            if (answer.matches("[A-E]")) {
                answerNumber = answer.charAt(0) - 'A' + 1;
            } else {
                try {
                    answerNumber = Integer.parseInt(answer);
                } catch (NumberFormatException e) {
                    log.warn("题目{}的答案{}格式无效", question.getId(), answer);
                    return 0.0;
                }
            }

            // 将数字转换为字符串键
            String scoreKey = String.valueOf(answerNumber);
            BigDecimal score = optionScores.get(scoreKey);

            if (score == null) {
                log.warn("题目{}的选项{}未找到对应分值", question.getId(), scoreKey);
                return 0.0;
            }

            log.info("题目{} 答案{} 对应选项{} 得分{}", question.getId(), answer, scoreKey, score);
            return score.doubleValue();
        } catch (Exception e) {
            log.error("计算题目分数时出错", e);
            return 0.0;
        }
    }

    public Map<String, String> getDimensionLevels(Long testId, Map<String, Double> dimensionScores) {
        List<Map<String, Object>> dimensions = psychologicalTestService.getTestDimensions(testId);
        Map<String, String> dimensionLevels = new HashMap<>();
        
        for (Map<String, Object> dimension : dimensions) {
            String dimensionKey = (String) dimension.get("dimensionKey");
            Double score = dimensionScores.get(dimensionKey);
            
            if (score != null) {
                // 获取分数范围，如果未配置则使用默认范围
                Object scoreRangeObj = dimension.get("score_range");
                double min = 0.0;
                double max = 100.0; // 默认范围0-100
                
                if (scoreRangeObj != null) {
                    try {
                        String[] range = scoreRangeObj.toString().split("-");
                        min = Double.parseDouble(range[0]);
                        max = Double.parseDouble(range[1]);
                    } catch (Exception e) {
                        log.warn("维度{}的分数范围配置无效: {}", dimensionKey, scoreRangeObj);
                    }
                }
                
                // 根据分数范围判定等级
                if (score <= min + (max - min) / 3) {
                    dimensionLevels.put(dimensionKey, "低");
                } else if (score <= min + (max - min) * 2 / 3) {
                    dimensionLevels.put(dimensionKey, "中");
                } else {
                    dimensionLevels.put(dimensionKey, "高");
                }
                
                log.info("维度{} 得分{} 范围{}-{} 评级{}", 
                    dimensionKey, score, min, max, dimensionLevels.get(dimensionKey));
            }
        }
        
        return dimensionLevels;
    }

    @Override
    public Double calculateTotalScore(Map<String, Double> dimensionScores) {
        return dimensionScores.values().stream()
            .mapToDouble(Double::doubleValue)
            .sum();
    }

    @Override
    public String getScoringType() {
        return "DIMENSION";
    }

    @Override
    public boolean validateAnswer(String answer) {
        if (answer == null || answer.trim().isEmpty()) {
            return false;
        }
        // 检查是否是有效的字母（A-E）或数字（1-5）
        return answer.matches("[A-E]") || (answer.matches("\\d+") && Integer.parseInt(answer) >= 1 && Integer.parseInt(answer) <= 5);
    }
} 